package com.module.imageloader

import android.content.Context
import android.view.View
import com.module.imageloader.cache.DiskCacheOptions
import com.module.imageloader.loaders.GlideLoader
import com.module.imageloader.loaders.ImageDelegate
import com.module.imageloader.option.ImageOptions
import java.io.File
import java.io.FileInputStream

/**
 * date        ：2020/7/14
 * author      ：蒙景博
 * description ：
 */
class ImageLoader private constructor() {

    companion object {

        @Volatile
        private var INSTANCES: ImageLoader? = null

        fun getDefault(): ImageLoader = INSTANCES ?: synchronized(this){ ImageLoader().also { INSTANCES = it }}
    }

    @Volatile
    private var mDelegate: ImageDelegate? = null

    @Volatile
    private var mDiskCacheOptions: DiskCacheOptions.Builder

    @Volatile
    private var mImageOptions: ImageOptions.Builder

    init {
        mDelegate = GlideLoader()
        mImageOptions = ImageOptions.Builder()
        mDiskCacheOptions = DiskCacheOptions.Builder()
    }

    fun diskCacheOptions(): DiskCacheOptions.Builder {
        return mDiskCacheOptions
    }

    fun with(context: Context): ImageOptions.Builder {
        return mImageOptions.setContext(context).setImageLoader(mDelegate)
    }

    /**
     * 暂停请求
     */
    fun pauseRequests(context: Context) {
        mDelegate?.pauseRequests(context)
    }

    /**
     * 暂停所有请求
     */
    fun pauseAllRequests(context: Context) {
        mDelegate?.pauseAllRequests(context)
    }

    /**
     * 恢复请求
     */
    fun resumeRequests(context: Context) {
        mDelegate?.resumeRequests(context)
    }

    /**
     * 清除磁盘缓存
     */
    fun clearDiskCache(context: Context) {
        mDelegate?.clearDiskCache(context)
    }

    /**
     * 清除View
     */
    fun clear(view: View) {
        mDelegate?.clear(view)
    }

    /**
     * 清除内存缓存
     */
    fun clearMemory(context: Context) {
        mDelegate?.clearMemory(context)
    }

    /**
     * 根据设定的级别，将内存缓存自动调节到合适的大小。
     */
    fun trimMemory(context: Context, level: Int) {
        mDelegate?.trimMemory(context, level)
    }

    /**
     * 获取磁盘缓存的数据大小，单位：KB
     */
    fun getDiskCacheSize(context: Context): Long {
        val options = diskCacheOptions().build()
        val diskCacheDirPath = options.diskCacheDirPath ?: context.filesDir.path
        val diskCacheFolderName = options.diskCacheFolderName
        val file = File("$diskCacheDirPath${File.separator}$diskCacheFolderName")
        var blockSize = 0L
        try {
            blockSize = if (file.isDirectory) getFileSizes(file) else getFileSize(file)
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return blockSize
    }

    private fun getFileSizes(file: File): Long {
        var size = 0L
        file.listFiles()?.forEach {
            if (it.isDirectory) {
                size += getFileSizes(it)
            } else {
                try {
                    size += getFileSize(it)
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }
        return size
    }

    private fun getFileSize(file: File): Long {
        var size = 0L
        if (file.exists()) {
            FileInputStream(file).use {
                size = it.available().toLong()
            }
        }
        return size
    }
}